package tasks

import contributors.*
import kotlinx.coroutines.*
import kotlin.coroutines.coroutineContext

//GlobalScope方式：顶层作用域，不依赖于父协程，父协程遇到异常或者取消后子协程不会自动结束，需要显示取消或等待
suspend fun loadContributorsNotCancellable(service: GitHubService, req: RequestData): List<User> {
    //下一步getRepoContributors请求会基于这一步的结果，而且同级别的只有这一个任务在执行，因此这里没必要用async
    val repos = service.getOrgRepos(req.org)
        .also { logRepos(req, it) }
        .body() ?: emptyList()
    //这里的请求具有并发关系，可以使用async来节省时间
    val asyncTasks = mutableListOf<Deferred<List<User>>>()
    repos.forEach { repo ->
        asyncTasks.add(
            //如果外层的协程job取消，这里的协程并不会随之结束，因为它在独立的顶层作用域
            GlobalScope.async {
//            async(Dispatchers.Default) {
                service.getRepoContributors(req.org, repo.name)
                    .also { logUsers(repo, it) }
                    .body() ?: emptyList()
            }
        )
    }
    //asyncTasks.awaitAll()得到的是List<List<User>>
    return asyncTasks.awaitAll().flatten().aggregate()
}